﻿#region copyright
//<copyright>
// Copyright(C) 2012 TrackerRealm Corporation
// This file is part of the open source project - Jazz. http://jazz.codeplex.com
// 
// Jazzfire is open software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License (AGPL) as published by the Free Software Foundation, version 3 of the License.
// 
// Jazzfire is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License (AGPL) for more details.
// 
// You should have received a copy of the GNU General Public License along with Jetfire.  If not, see <http://www.gnu.org/licenses/>.
//
// REMOVAL OF THIS NOTICE IS VIOLATION OF THE COPYRIGHT. 
//</copyright>
#endregion
# region using
using System;
using System.Linq;
using System.Collections.Generic;
using TrackerRealm.Jazz.Client;
using TrackerRealm.Jazz.Client.Custom;
# endregion

namespace TrackerRealm.Jazz.WindowsForm
{
    /// <summary>
    /// GroupToDo implements a simple to do item.
    /// </summary>
    [Jazz]
    public class GroupToDo : jName
    {
        # region Constructor
        /// <summary>
        /// Instantiate a to do item
        /// </summary>
        /// <param name="nexus"></param>
        /// <param name="name">name of the to do item</param>
        public GroupToDo(ClientNexus nexus, string name) : base(null, name)
        {
            this.Initialize(nexus);
            nexus.Bind(this);
        }
        /// <summary>
        /// Initialize properties
        /// </summary>
        void Initialize(ClientNexus nexus)
        {
            if (!this.IsEmpty)
            {
                this.Creator = nexus.LoginProfile;
                // Move item to To Do Workspace
                jWorkspace ws = nexus.Cache.OfType<jWorkspace>().SingleOrDefault(s => s.Name == "To Do Workspace");
                if (ws != null)
                    ws.Move(this);
            }
        }
        # endregion
        # region Properties
        /// <summary>
        /// Cast the ClientNexus
        /// </summary>
        private ClientNexus Nexus
        {
            get { return (ClientNexus)this.ClientNexus; }
        }
        /// <summary>
        /// The person who creates the to do item and defines it
        /// </summary>
        public jProfile Creator
        {
            get;
            private set;
        }
        /// <summary>
        /// The person assigned to the to do item
        /// </summary>
        public jProfile AssignedTo
        {
            get;
            private set;
        }
        /// <summary>
        /// The name of the to do item
        /// </summary>
        public override string Name
        {
            get { return base.Name; }
            protected set { base.Name = value; }
        }
        /// <summary>
        /// The 'what' of the to do item
        /// </summary>
        public string Description
        {
            get;
            [GrantStates("Started"), GrantProperty("Creator")]
            set;
        }
        /// <summary>
        /// Comments from the assigned to person
        /// </summary>
        public string AssignedTo_Comments
        {
            get;
            [GrantStates("Assigned"), GrantProperty("AssignedTo")]
            set;
        }
        public string Approver_Comments
        {
            get;
            [GrantStates("Finished"), GrantRoles("Manager")]
            set;
        }
        # endregion
        # region Properties used in Grant Constructs
        /// <summary>
        /// Identifies if the logged in user is the Creator
        /// </summary>
        bool IsCreator
        {
            get { return this.Creator == this.Nexus.LoginProfile; }
        }
        /// <summary>
        /// Identifies if the logged user is the person assgined to work the to do item
        /// </summary>
        bool IsMyItem
        {
            get 
            {   // if no one is assigned to the item, then return true
                if (this.AssignedTo == this.Nexus.LoginProfile.Class.EmptyInstance)
                    return true;
                // OR logged in user must be assigned to the item
                return this.AssignedTo == this.Nexus.LoginProfile;
            }
        }
        /// <summary>
        /// Identifies when and whom can delete the to do item
        /// </summary>
        bool CanDelete
        {
            get
            {
                if (!this.IsValid)
                    return false;
                if (this.Nexus.LoginRoles.Contains("Manager"))
                    return this.CurrentState.Name != "Approved";
                switch (this.CurrentState.Name)
                {
                    case "Started":
                        if (this.Nexus.LoginProfile == this.Creator)
                            return true;
                        break;
                    case "Defined":
                        if (this.Nexus.LoginProfile == this.AssignedTo)
                            return true;
                        break;
                }
                return false;
            }
        }
        # endregion
        # region Public Methods
        /// <summary>
        /// The creator can mark the definition complete
        /// </summary>
        [GrantStates("Started"), GrantProperty("IsCreator")]
        public void Definition_Complete()
        {
            this.EnterState("Defined");
        }
        /// <summary>
        /// Someone chooses to own the to do item
        /// </summary>
        [GrantStates("Defined"), GrantProperty("IsMyItem")]
        public void Claim_Task()
        {
            this.EnterState("Assigned");
            this.AssignedTo = this.Nexus.LoginProfile;
        }
        /// <summary>
        /// The assigned person marks the to do item as finished
        /// </summary>
        [GrantStates("Assigned"), GrantProperty("IsMyItem")]
        public void Finish()
        {
            this.EnterState("Finished");
        }
        /// <summary>
        /// The Manager approves the to do item
        /// </summary>
        [GrantStates("Finished"), GrantRoles("Manager")]
        public void Approve()
        {
            this.EnterState("Approved");
        }
        /// <summary>
        /// The Manager rejects the finish action
        /// </summary>
        [GrantStates("Finished"), GrantRoles("Manager")]
        public void Reject()
        {
            this.EnterState("Assigned");
        }
        /// <summary>
        /// Delete the to do item
        /// </summary>
        [GrantProperty("CanDelete")]
        public void Delete()
        {
            this.EnterState("Deleted");
        }
        # endregion
        # region States
        /// <summary>
        /// Enters the Started state when the to do item is created
        /// </summary>
        [StartState]
        void Started()  { }
        /// <summary>
        /// Is Defined when the creator finished the description
        /// </summary>
        [State]
        void Defined()  { }
        /// <summary>
        /// Is assigned when someone chooses to own the to do item
        /// </summary>
        [State]
        void Assigned() { }
        /// <summary>
        /// Is finished when the assigned to person marks it finished
        /// </summary>
        [State]
        void Finished() { }
        /// <summary>
        /// Is approved when the manager marks the to do item approved
        /// </summary>
        [FinalState]
        void Approved() { }
        /// <summary>
        /// Is deleted when someone deletes the to to item
        /// </summary>
        [FinalState]
        void Deleted()
        {
            base._Delete();
        }
        # endregion
    }
}